Previous Book Contents Book Index Next

Inside Macintosh: QuickDraw GX Objects /
Chapter 7 - View-Related Objects / Using View-Related Objects


Using View Devices

This section demonstrates how to use QuickDraw GX view devices. It shows how you can

Creating and Manipulating View Device Objects

Normally, your application needs to create view device objects only for offscreen drawing. QuickDraw GX creates view device objects for all attached screen devices at startup. If you do need to create a view device object, QuickDraw GX provides the GXNewViewDevice function, to which you must supply a view group reference and a bitmap shape representing the device's imaging area and characteristics. You can also create a new view device object by copying an existing one, using the GXCopyToViewDevice function.

Once you have created a view device object, you can customize its features using the techniques described in the following sections.

You can test if two view device-object references refer to the same view device object by simply testing the references for equality. You can also test a view device for equality with another view device with the GXEqualViewDevice function. For two view device objects to be equal, their clips, mappings, bitmap shapes, and attributes must be identical, and they must be in the same view group, represent the same Macintosh graphics device (same GDevice record), and point to the same pixel image, color set, and color profile. Their tag lists need not be identical. View device object copies created with the GXCopyToViewDevice function are always equal to the view device from which they were copied.

To delete your application's reference to a view device object, call the GXDisposeViewDevice function. Because view device objects have no owner count, calling GXDisposeViewDevice actually releases the memory allocated for that view device object, and invalidates all other references to it.

Listing 7-9 is a portion of a printer driver routine that sets up a default printing
view device. It first sets up a bitmap structure with default values, and then creates
a bitmap shape to pass to GXNewViewDevice. The view group for this view device
is gxScreenViewDevices, because it is to be used for printing, not offscreen
drawing.

Listing 7-9 Creating a new view device

gxBitmap       aBitmap;
gxViewDevice   vd;
aBitmap.pixelSize = 1;
aBitmap.rowBytes  = 0;
aBitmap.width     = 0;
aBitmap.height    = 0;
aBitmap.image     = nil;
aBitmap.space     = gxNoSpace;
aBitmap.set       = nil;
aBitmap.profile   = nil;

theBitmap = GXNewBitmap(&aBitmap, nil);
./* error-check here (not shown) */
.
.
vd = GXNewViewDevice(gxScreenViewDevices, theBitmap);
./* error-check here (not shown) */
.
.
When the driver is finished with the view device, it disposes of it with this line:

GXDisposeViewDevice(vd);
Listing 7-10 demonstrates creating a new view device by using the GXCopyToViewDevice function. Like Listing 7-2 on page 7-44, it is part of a
routine that creates an offscreen view group (newGroup) that is a copy of an
existing view group (group). For each view device in the onscreen view group,
the routine creates a copy and assigns it to the offscreen view group.

The routine decrements the count variable to control incrementing through the list
of view devices (list) belonging to the onscreen view group.

Listing 7-10 Copying the view devices from one view group to another

long           deviceCount = GXGetViewGroupViewDevices(group,nil); 
long           count = deviceCount;
gxViewDevice   *deviceList = (void *)NewPtr(deviceCount * 
                              sizeof(gxViewDevice));
gxViewDevice   *list = deviceList;
GXGetViewGroupViewDevices(group, deviceList);
while (count-- > 0)
{
   GXSetViewDeviceViewGroup(*list = GXCopyToViewDevice(nil, 
                              *list), newGroup);
   list++;
}
The GXNewViewDevice function is described on page 7-98. The GXDisposeViewDevice function is described on page 7-99.
The GXCopyToViewDevice function is described on page 7-100. The GXEqualViewDevice function is described on page 7-101.

Manipulating View Device Object Properties

This section describes how to manipulate the bitmap, view group, and attributes properties of a view device object:

How to manipulate other view device properties is described in subsequent sections, starting with "Getting and Setting a View Device's Clip and Mapping" on page 7-56.

Getting and Setting a View Device's Bitmap

The following code fragment is a function that uses GXGetViewDeviceBitmap to gain access to a copy of the color set of a view device, clone its reference (so it won't be deleted when its bitmap is disposed of), and then return it as a function result. The function needs the bitmap shape itself only temporarily, and therefore disposes of it after extracting the color set reference from it.

gxColorSet GetViewDeviceColorSet(gxViewDevice source)
{
   register gxShape     bitmapShape = 
                                 GXGetViewDeviceBitmap(source);
   register gxColorSet  result = GetShapeColorSet(bitmapShape);
   if (result)
      GXCloneColorSet(result);
   GXDisposeShape(bitmapShape);
   return result;
}
The following code fragment is a function that uses GXSetViewDeviceBitmap to assign a color profile to a view device. The function disposes of its reference to the bitmap shape after assigning it to the view device.

void SetViewDeviceColorProfile(gxViewDevice target, 
                                 gxColorProfile profile)
{
   register gxShape bitmapShape = GXGetViewDeviceBitmap(target);

   SetShapeColorProfile(bitmapShape, profile);
   GXSetViewDeviceBitmap(target, bitmapShape);
   GXDisposeShape(bitmapShape);
}
The GXGetViewDeviceBitmap function is described on page 7-107; the GXSetViewDeviceBitmap function is described on page 7-108.

Getting and Setting a View Device's View Group

You can use the GXGetViewDeviceViewGroup function to retrieve the view group that a view device belongs to, and you can use the GXSetViewDeviceViewGroup to change the view group of a view device. Listing 7-10 on page 7-54 shows an example of using GXSetViewDeviceViewGroup to reassign the copy of a view device from one view group to another.

The GXGetViewDeviceViewGroup function is described on page 7-109; the GXSetViewDeviceViewGroup function is described on page 7-109.

Getting and Setting a View Device's Attributes and Tag References

You can examine the attributes of a view device object using the GXGetViewDeviceAttributes function. You can set the attributes of a view device object using the GXSetViewDeviceAttributes function. By setting attributes, you can influence whether the device bitmap is placed on an accelerator card and whether the device is active or inactive.

You can examine the list of references to tag objects currently associated with a view device object using the GXGetViewDeviceTags function. Once you create a tag
object, you can attach it to a view device object using the GXSetViewDeviceTags function. You can attach as many tag objects as you like to a view device object.

Tag objects and the basic functions for manipulating them are described in the chapter "Tag Objects" in this book. That chapter also lists the common tag types defined and reserved by Apple Computer, Inc.

The GXGetViewDeviceAttributes function is described on page 7-110; the GXSetViewDeviceAttributes function is described on page 7-111. View device attributes are described in the section "View Device Attributes" on page 7-27.

The GXGetViewDeviceTags function is described on page 7-112. The GXSetViewDeviceTags function is described on page 7-113.

Getting and Setting a View Device's Clip and Mapping

The clip and mapping properties of a view device control its active imaging area, its scale (pixel size), and its position in global space. For onscreen view devices and printing view devices, you cannot change the clip or mapping properties; they are set by QuickDraw GX. For offscreen view devices, you can set the clip and mapping yourself. The functions you use are GXGetViewDeviceClip, GXSetViewDeviceClip, GXGetViewDeviceMapping, and GXSetViewDeviceMapping.

Listing 7-11 is a utility routine that returns a mapping matrix that converts from local space (or from the identity mapping, if the view port is nil) to device space (or to
global space, if the view device is nil). It uses GXGetViewDeviceMapping to retrieve the view device's mapping matrix. (If the view device is nil, the routine uses the mapping matrix returned by the GXGetViewPortGlobalMapping function.) The routine also makes use of the MapMapping function, described in the mathematics chapter of Inside Macintosh: QuickDraw GX Environment and Utilities.

Listing 7-11 Returning the mapping from local to device space

static void GetSpaceMapping(gxViewPort port, gxViewDevice device, 
                              gxMapping *map)
{
   if (port)
      GXGetViewPortGlobalMapping(port, map);
   else
      ResetMapping(map);

   if(device) 
   {
      gxMapping temp;
      MapMapping(map, GXGetViewDeviceMapping(device, &temp));
   }
}
The following code fragment is part of a printer driver routine that sets up a default view device. This section of code rescales the mapping matrix (vdMapping) of the view device (vd) from the default resolution (72 ppi, as specified by the identity matrix) to the horizontal and vertical resolution of the printer (kHorizHighRes and kVertHighRes). To do the scaling, the code uses the ScaleMapping function, described in the mathematics chapter of Inside Macintosh: QuickDraw GX Environment and Utilities. It then uses GXSetViewDeviceMapping to assign the scaled mapping to the view device.

Fixed    xScale;
Fixed    yScale;

xScale = FixRatio(kHorizHighRes, 72);
yScale = FixRatio(kVertHighRes, 72);
      
ResetMapping(&vdMapping);
ScaleMapping(&vdMapping, xScale, yScale, ff(0), ff(0));
GXSetViewDeviceMapping(vd, &vdMapping);
The GXGetViewDeviceClip function is described on page 7-102; the GXSetViewDeviceClip function is described on page 7-103.

The GXGetViewDeviceMapping function is described on page 7-105; the GXSetViewDeviceMapping function is described on page 7-106.

Identifying a Shape's View Devices

The GXGetShapeGlobalViewDevices function returns a list of all view devices that a shape would actually appear in if it were drawn. The function can test the shape against all the shape's view ports, or you can specify a single view port for the test.

You can use GXGetShapeGlobalViewDevices to avoid the overhead of testing the drawing characteristics (such as the colors) of shapes on devices that they cannot be drawn to.

Listing 7-12 is part of a library routine that sets up a data structure for offscreen drawing through a given view port. This part of the code creates a full shape--which covers all of coordinate space--and passes it to GXGetShapeGlobalViewDevices to derive a count of all view devices that could be drawn on through the given port. (Note that, for the purpose of retrieving all the view devices of a view port, you could also use the GXGetViewPortViewDevices function.)

Listing 7-12 Setting up a data structure for offscreen drawing

viewPortBuffer NewViewPortBuffer(gxViewPort port)
{
   viewPortBuffer          buffersHandle;
   viewPortBufferRecord    *buffers;
   gxTransform             xform;
   gxShape                 area;
   long                    deviceCount;
   short                   i;

   NilParamReturnNil(port);      /* error check port parameter */
   area = GXNewShape(gxFullType);
   xform = GXNewTransform();
   GXSetTransformViewPorts(xform, 1, &port);
   GXSetShapeTransform(area, xform);
   GXDisposeTransform(xform);
   deviceCount = GXGetShapeGlobalViewDevices(area, port, nil);
.
.  /* continued as Listing 7-13 on page 7-61 */
.
The GXGetShapeGlobalViewDevices function is described on page 7-115.

Measuring a Shape in Device Space

You can use view device functions to measure a shape on a device in three ways:

The GXGetShapeDeviceBounds function determines whether any part of a shape intersects a view device, and if so, returns the bounding rectangle of that part of the shape in device coordinates. You can thus use GXGetShapeDeviceBounds to measure the size of a shape on a view device and to compare it with other shapes on the device. (To measure a shape in the local space of a view port, you can use the GXGetShapeLocalBounds function; to measure a shape in the global space of a view group, use GXGetShapeGlobalBounds.)

The following is a fragment of a function that converts a QuickDraw GX shape on a device into a QuickDraw picture. It uses GXGetShapeDeviceBounds to get the shape's bounding rectangle on the device, converts that rectangle into a QuickDraw rect structure, further converts it to QuickDraw local coordinates, and uses that to define the picture bounding rectangle. After that, the function converts the shape itself (not shown).

   GXGetShapeDeviceBounds(theShape, 0, 0, &shapeBounds);
   picRect.left      = FixedToInt(shapeBounds.left);
   picRect.top       = FixedToInt(shapeBounds.top);
   picRect.right     = FixedToInt(shapeBounds.right);
   picRect.bottom    = FixedToInt(shapeBounds.bottom);
   GlobalToLocal((Point*) &picRect.top);
   GlobalToLocal((Point*) &picRect.bottom);
      
   thePicture = OpenPicture(&picRect);
.
.  /* convert the shape (not shown) */
.
The QuickDraw functions GlobalToLocal and OpenPicture, and the data types Point and Rect are described in Inside Macintosh: Imaging With QuickDraw.

Note
You do not need to write special functions to convert
QuickDraw pictures into QuickDraw GX shapes. You can use
the QuickDraw-to-QuickDraw GX translator for that; see the
Macintosh environment chapter of Inside Macintosh: QuickDraw GX Environment and Utilities.
The GXGetShapeDeviceBounds function is described on page 7-116. The GXGetShapeDeviceArea function is described on page 7-118.
The GXGetShapeDeviceColors function is described on page 7-119.

GXGetShapeGlobalBounds function is described on page 7-125.
The GXGetShapeLocalBounds function, described on page 7-96.

Hit-Testing a Shape on a Device

The GXHitTestDevice function is one of several hit-testing functions provided
by QuickDraw GX. Hit-testing in general is described in the chapter "Introduction to QuickDraw GX" in this book; shape parts for hit-testing are described in the chapter "Transform Objects" in this book.

You use GXHitTestDevice instead of GXHitTestShape or GXHitTestPicture--or before them--when it is important to take into account whether a shape is actually visible on a device. Unlike GXHitTestShape and GXHitTestPicture, GXHitTestDevice accounts for clipping and does not return successful hits for shapes that are not actually drawn.

Another significant difference is that the tolerance for GXHitTestDevice defines a rectangular area of pixels, not the circular geometry area used by GXHitTestShape and GXHitTestPicture. Thus you can use the tolerance value for GXHitTestDevice as something like a clip area, expanding it to cover an entire window or contracting it to one or a few complete pixels.

What GXHitTestDevice does not do that GXHitTestShape and GXHitTestPicture do is analyze the parts of a shape. If you are hit-testing in order to highlight specific parts of a shape, for example, you can first call GXHitTestDevice to determine which shape was actually hit, and then call GXHitTestShape or GXHitTestPicture to determine the part or parts to highlight.

The GXHitTestDevice function is described on page 7-120. The GXHitTestShape function is described in the chapter "Shape Objects" in this book. The GXHitTestPicture function is described in the picture shapes chapter of Inside Macintosh: QuickDraw GX Graphics.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
7 JUL 1996